home *** CD-ROM | disk | FTP | other *** search
- /*********************************************************
- C# Threads demo
- Example submitted by Chua Chee Wee, Singapore
- **********************************************************/
- using System;
- using System.Threading;
- using System.Drawing;
- using System.Runtime.InteropServices;
-
- namespace ThrdDemo {
-
-
- public class ThreadSortForm : System.Windows.Forms.Form {
- public delegate void ThreadDoneDelegate();
- public delegate void VisualSwapDelegate();
-
- class TSortHandler {
- private int[] FSortArray;
- protected System.Windows.Forms.Panel FPanel;
- protected int FI, FA, FJ, FB;
- protected event VisualSwapDelegate FDoVisualSwap;
- Pen pen;
- protected void PaintLine(System.Drawing.Graphics Canvas, int I, int Len) {
- Canvas.DrawLine(pen, 0, I*2+1, Len, I*2+1);
- }
- protected void DoVisualSwap() {
- System.Drawing.Graphics Canvas = FPanel.CreateGraphics();
-
- // erase the line, by painting over it with the
- // background color
- pen = new Pen(FPanel.BackColor, 1);
- PaintLine(Canvas, FI, FA);
- PaintLine(Canvas, FJ, FB);
-
- pen = new Pen(Color.Red, 1);
- PaintLine(Canvas, FI, FB);
- PaintLine(Canvas, FJ, FA);
-
- Canvas.Dispose();
- }
-
- protected void VisualSwap(int A, int B, int I, int J) {
- FA = A;
- FB = B;
- FI = I;
- FJ = J;
- if (FDoVisualSwap!=null)
- FPanel.Invoke(FDoVisualSwap);
- }
-
- public event ThreadDoneDelegate OnThreadDone;
-
-
- public void Execute() {
- Sort(FSortArray);
- if (OnThreadDone!=null)
- OnThreadDone();
- }
-
- public TSortHandler(System.Windows.Forms.Panel Panel, int[] SortArray) {
- FPanel = Panel;
- // The assignment below is assignment by reference
- FSortArray = SortArray;
- FDoVisualSwap += new VisualSwapDelegate(this.DoVisualSwap);
- }
-
- public virtual void Sort(int[] A) {
- }
- }
-
- class TBubbleSortHandler : TSortHandler {
- public TBubbleSortHandler(System.Windows.Forms.Panel Panel,
- int[] SortArray): base(Panel, SortArray) {
- }
-
- public override void Sort(int[] A) {
-
- for(int I = A.GetUpperBound(0);I>=A.GetLowerBound(0); I--)
- for(int J = A.GetLowerBound(0); J<A.GetUpperBound(0); J++)
- if (A[J] > A[J + 1])
- {
- VisualSwap(A[J], A[J + 1], J, J + 1);
- int T = A[J];
- A[J] = A[J + 1];
- A[J + 1] = T;
- // superfluous code, but shows how to check if thread has been terminated
- // if (Thread.CurrentThread.ThreadState==ThreadState.Stopped) return;
- }
- }
- }
-
- class TSelectionSortHandler : TSortHandler {
- public TSelectionSortHandler(System.Windows.Forms.Panel Panel,
- int[] SortArray): base(Panel, SortArray) {
- }
-
- public override void Sort(int[] A) {
-
- for(int I = A.GetLowerBound(0); I<A.GetUpperBound(0); I++)
- for(int J = A.GetUpperBound(0); J>=I+1; J--)
- if (A[I] > A[J])
- {
- VisualSwap(A[I], A[J], I, J);
- int T = A[I];
- A[I] = A[J];
- A[J] = T;
- // superfluous code, but shows how to check if thread has been terminated
- // if (Thread.CurrentThread.ThreadState==ThreadState.Stopped) return;
- }
- }
- }
-
- class TQuickSortHandler : TSortHandler {
- public TQuickSortHandler(System.Windows.Forms.Panel Panel,
- int[] SortArray): base(Panel, SortArray) {
- }
-
- private void QuickSort(int[] A, int iLo, int iHi) {
-
- int Lo = iLo;
- int Hi = iHi;
- int Mid = A[(Lo + Hi) / 2];
- do {
- while (A[Lo] < Mid) Lo++;
- while (A[Hi] > Mid) Hi--;
- if (Lo <= Hi) {
- VisualSwap(A[Lo], A[Hi], Lo, Hi);
- int T = A[Lo];
- A[Lo] = A[Hi];
- A[Hi] = T;
- Lo++;
- Hi--;
- }
- } while (Lo <= Hi);
- if (Hi > iLo) QuickSort(A, iLo, Hi);
- if (Lo < iHi) QuickSort(A, Lo, iHi);
- // superfluous code, but shows how to check if thread has been terminated
- // if (Thread.CurrentThread.ThreadState==ThreadState.Stopped) return;
- }
-
- public override void Sort(int[] A) {
- QuickSort(A, A.GetLowerBound(0), A.GetUpperBound(0));
- }
- }
-
- public ThreadSortForm() {
- this.InitializeComponent();
- BubbleSortArray = new int[115];
- QuickSortArray = new int[115];
- SelectionSortArray = new int[115];
- RandomizeArrays();
- }
-
- public static void Main() {
- System.Windows.Forms.Application.Run(new ThreadSortForm());
- }
-
- private void InitializeComponent()
- {
- this.PanelBubbleSort = new System.Windows.Forms.Panel();
- this.PanelSelectionSort = new System.Windows.Forms.Panel();
- this.PanelQuickSort = new System.Windows.Forms.Panel();
- this.btnSort = new System.Windows.Forms.Button();
- this.BubbleSort = new System.Windows.Forms.Label();
- this.SelectionSort = new System.Windows.Forms.Label();
- this.QuickSort = new System.Windows.Forms.Label();
- this.SuspendLayout();
- //
- // PanelBubbleSort
- //
- this.PanelBubbleSort.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
- this.PanelBubbleSort.Location = new System.Drawing.Point(8, 24);
- this.PanelBubbleSort.Name = "PanelBubbleSort";
- this.PanelBubbleSort.Size = new System.Drawing.Size(177, 233);
- this.PanelBubbleSort.TabIndex = 0;
- this.PanelBubbleSort.Paint += new System.Windows.Forms.PaintEventHandler(this.panel1_Paint);
- //
- // PanelSelectionSort
- //
- this.PanelSelectionSort.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
- this.PanelSelectionSort.Location = new System.Drawing.Point(192, 24);
- this.PanelSelectionSort.Name = "PanelSelectionSort";
- this.PanelSelectionSort.Size = new System.Drawing.Size(177, 233);
- this.PanelSelectionSort.TabIndex = 1;
- this.PanelSelectionSort.Paint += new System.Windows.Forms.PaintEventHandler(this.panel2_Paint);
- //
- // PanelQuickSort
- //
- this.PanelQuickSort.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
- this.PanelQuickSort.Location = new System.Drawing.Point(376, 24);
- this.PanelQuickSort.Name = "PanelQuickSort";
- this.PanelQuickSort.Size = new System.Drawing.Size(177, 233);
- this.PanelQuickSort.TabIndex = 2;
- this.PanelQuickSort.Paint += new System.Windows.Forms.PaintEventHandler(this.panel3_Paint);
- //
- // btnSort
- //
- this.btnSort.Location = new System.Drawing.Point(416, 264);
- this.btnSort.Name = "btnSort";
- this.btnSort.Size = new System.Drawing.Size(136, 25);
- this.btnSort.TabIndex = 3;
- this.btnSort.Text = "Start sorting";
- this.btnSort.Click += new System.EventHandler(this.btnSort_Click);
- //
- // BubbleSort
- //
- this.BubbleSort.Location = new System.Drawing.Point(8, 8);
- this.BubbleSort.Name = "BubbleSort";
- this.BubbleSort.Size = new System.Drawing.Size(128, 13);
- this.BubbleSort.TabIndex = 4;
- this.BubbleSort.Text = "Bubble Sort";
- //
- // SelectionSort
- //
- this.SelectionSort.Location = new System.Drawing.Point(192, 8);
- this.SelectionSort.Name = "SelectionSort";
- this.SelectionSort.Size = new System.Drawing.Size(136, 13);
- this.SelectionSort.TabIndex = 5;
- this.SelectionSort.Text = "Selection Sort";
- //
- // QuickSort
- //
- this.QuickSort.Location = new System.Drawing.Point(376, 8);
- this.QuickSort.Name = "QuickSort";
- this.QuickSort.Size = new System.Drawing.Size(128, 13);
- this.QuickSort.TabIndex = 6;
- this.QuickSort.Text = "Quick Sort";
- //
- // ThreadSortForm
- //
- this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
- this.ClientSize = new System.Drawing.Size(562, 295);
- this.Controls.Add(this.SelectionSort);
- this.Controls.Add(this.BubbleSort);
- this.Controls.Add(this.btnSort);
- this.Controls.Add(this.PanelQuickSort);
- this.Controls.Add(this.PanelSelectionSort);
- this.Controls.Add(this.PanelBubbleSort);
- this.Controls.Add(this.QuickSort);
- this.Name = "ThreadSortForm";
- this.Text = "Thread Sorting Demo";
- this.ResumeLayout(false);
- }
- private System.Windows.Forms.Panel PanelBubbleSort;
- private System.Windows.Forms.Panel PanelSelectionSort;
- private System.Windows.Forms.Panel PanelQuickSort;
- private System.Windows.Forms.Button btnSort;
- private System.Windows.Forms.Label BubbleSort;
- private System.Windows.Forms.Label SelectionSort;
- private System.Windows.Forms.Label QuickSort;
-
- private int[] BubbleSortArray, SelectionSortArray, QuickSortArray;
-
- private System.Random Random;
- private int ThreadsRunning;
-
- // It is possible that ThreadDone is called by a thread while it is executing,
- // and that, they're both decrementing the ThreadsRunning variable at the
- // same time. locking it will ensure that ThreadsRunning is not decremented
- // at the same time. Highly unlikely that ThreadDone will be called at
- // the same time, since the sorting algorithms' speed varies greatly.
- // However, it is good practice to lock a block of code that is likely
- // to be executed at the same time, ie, make no assumptions when threads
- // are involved!!!
- public void ThreadDone() {
- lock(this) {
- if (--ThreadsRunning==0) {
- btnSort.Enabled = true;
- }
- }
- }
-
- // Randomizes the 3 arrays with random seed from the current time
- private void RandomizeArrays() {
-
- Random = new System.Random(unchecked((int)DateTime.Now.Ticks));
- for (int I=0;I<BubbleSortArray.Length;I++){
- BubbleSortArray[I] = Random.Next(170);
- }
- System.Array.Copy(BubbleSortArray, QuickSortArray, BubbleSortArray.Length);
- System.Array.Copy(BubbleSortArray, SelectionSortArray, BubbleSortArray.Length);
- }
-
- private void btnSort_Click(object sender, System.EventArgs e) {
- RandomizeArrays();
- Refresh();
- ThreadsRunning = 3;
- btnSort.Enabled = false;
-
- TSelectionSortHandler SelectionSortHandler = new TSelectionSortHandler(PanelSelectionSort, SelectionSortArray);
- SelectionSortHandler.OnThreadDone += new ThreadDoneDelegate(this.ThreadDone);
-
- TQuickSortHandler QuickSortHandler = new TQuickSortHandler(PanelQuickSort, QuickSortArray);
- QuickSortHandler.OnThreadDone += new ThreadDoneDelegate(this.ThreadDone);
-
- TBubbleSortHandler BubbleSortHandler = new TBubbleSortHandler(PanelBubbleSort, BubbleSortArray);
- BubbleSortHandler.OnThreadDone += new ThreadDoneDelegate(this.ThreadDone);
-
- Thread SelectionSortThread = new Thread(new ThreadStart(SelectionSortHandler.Execute));
- SelectionSortThread.Name = "Selection Sort";
- SelectionSortThread.IsBackground = true;
-
- Thread QuickSortThread = new Thread(new ThreadStart(QuickSortHandler.Execute));
- QuickSortThread.Name = "Quick Sort";
- QuickSortThread.IsBackground = true;
-
- Thread BubbleSortThread = new Thread(new ThreadStart(BubbleSortHandler.Execute));
- BubbleSortThread.Name = "Bubble Sort";
- BubbleSortThread.IsBackground = true;
-
- SelectionSortThread.Start();
- QuickSortThread.Start();
- BubbleSortThread.Start();
-
- }
-
- private void PaintArray(System.Drawing.Graphics canvas, int[] A) {
- Pen redPen = new Pen(Color.Red, 1);
- for (int I=0;I<A.Length;I++) {
- canvas.DrawLine(redPen, 0, I*2+1, A[I], I*2+1);
- }
- }
-
- private void panel1_Paint(object sender, System.Windows.Forms.PaintEventArgs e) {
- PaintArray(e.Graphics, BubbleSortArray);
- }
-
- private void panel2_Paint(object sender, System.Windows.Forms.PaintEventArgs e) {
- PaintArray(e.Graphics, SelectionSortArray);
- }
-
- private void panel3_Paint(object sender, System.Windows.Forms.PaintEventArgs e) {
- PaintArray(e.Graphics, QuickSortArray);
- }
-
- }
- }
-
-